package parser;

import java.util.ArrayList;

import residue.AbstractResidue;
import residue.GenericComposedResidue;
import residue.GenericMonosaccharideResidue;
import residue.GenericSubstituentResidue;
import utils.TreeTools;



public class IupacBranch {

	

	private String sequence;
	protected String id="";
	private String ctId="";
	protected String parentId="";
	protected int level;
	protected int rank; //TODO ? fix the rank according to iupac sorting algorithm
	private int iupacLength=0;
	private int ctLength=0;
	private boolean isExpanded=false;

	private ArrayList<CTBranch> ctBranches = new ArrayList<CTBranch>();
	
	private IupacTree tree = null; // keep the tree ref in each branch
	
	private ArrayList<IupacBranch> subbranches = new ArrayList<IupacBranch>();
	protected ArrayList<IupacResidue> residues = new ArrayList<IupacResidue>();
	
	int openingSquareBracketCount ;
	int closingSquareBracketCount ;
	int openingParenthesisCount ;
	int closingParenthesisCount ;
	int openingCurlyBracketCount ;
	int closingCurlyBracketCount ;
	
	/*Constructor */
	protected IupacBranch(String sequence)
	{
		this.sequence=sequence;
	}
	protected IupacBranch()
	{
		
	}
	
	/*Accessor */
	public ArrayList<IupacBranch> getSubbranchesList() {
		return subbranches;
	}
	
	public ArrayList<IupacResidue> getResiduesList() {
		return residues;
	}
	
	public ArrayList<CTBranch> getCtBranches() {
		return ctBranches;
	}
	
//	public void setCtBranches(ArrayList<CTBranch> ctBranches) {
//		this.ctBranches = ctBranches;
//	}
	
	public boolean isExpanded() {
		return isExpanded;
	}
	public void setExpanded(boolean isExpanded) {
		this.isExpanded = isExpanded;
	}
	
	public void setIupacLength() {
		this.iupacLength = residues.size();
	}
	public int getIupacLength() {
		return this.iupacLength;
	}

	public void setCtLength() {
		
		int nbComposedResidue=0;
		
		for(int i =0; i<this.residues.size();i++)
		{
//			System.out.println("IupacBranch.setCtLength() residues.get(i).residue.getClass() : " + residues.get(i).getAbstractResidue().getClass());
			
			
//			//if the abstractResidue is a composed abstractResidue add 1 to counter
//			if(this.residues.get(i).residue.isGenericComposedResidue())
			AbstractResidue aRes = this.residues.get(i).getAbstractResidue();
			if(aRes.isGenericComposedResidue())
			{
				//GenericComposedResidue comp = (GenericComposedResidue)aRes;
				nbComposedResidue+=((GenericComposedResidue)aRes).getSubstituents().size();
				//ComposedResidue++;
//				System.out.println("IupacBranch.setCtLength() nbSubstituent of ComposedResidue : " + nbComposedResidue);
			}
		}
		this.ctLength = this.residues.size() + nbComposedResidue;
	}
	
	public int getCtLength() {
		return ctLength;
	}

	public String getSequence() {
	return sequence;
	}

	public void setSequence(String sequence) {
		this.sequence = sequence;
	}
	
	public String getId() {
		if(id==null){return "0";}
		return id;
	}
	
	public void setId(String id) {
		this.id = id;
	}
	
	public String getCTId() {
		if(ctId==null){return "0";}
		return ctId;
	}
	
	public void setCTId(String ctId) {
		this.ctId = ctId;
	}
	
	public String getParentId() {
		return parentId;
	}
	
	public void setParentId(String rootId) {
		this.parentId = rootId;
	}
	
	public int getLevel() {
		return level;
	}
	
	public void setLevel(int level) {
		this.level = level;
	}
	
	public int getRank() {
		return rank;
	}
	
	public void setRank(int rank) {
		this.rank = rank;
	}

	
	
	public IupacTree getTree() {
		return tree;
	}
	
	public void setTree(IupacTree tree) {
		this.tree = tree;
	}
	
	public int findRank(ArrayList<IupacBranch> tree) {
		int rank = -1;
		try
		{
			rank =(TreeTools.getChildrenBranches(this, tree)).size();
		}
		catch(Exception ex)
		{
			System.err.println("IupacBranch findRank : " + ex.getMessage());
		}
		return rank;
	}
	
	/*Methods */
	protected boolean isBranching()
	{
		if(sequence.contains(Constants.openingSquareBracket.toString()) || sequence.contains(Constants.closingSquareBracket.toString()))
		{
//			System.out.println("IupacBranch.isBranching() is TRUE: " + sequence);
			return true;
		}
//		System.out.println("IupacBranch.isBranching() is FALSE: " + sequence);
		return false;
	}
	
	
	
	protected IupacBranch getRootFromBranch()
	{
		String root_seq = this.sequence.substring(this.sequence.lastIndexOf(Constants.closingSquareBracket)+1);
		IupacBranch root = new IupacBranch(root_seq);
		
		root.level = this.level;
		root.rank = this.rank;
//		root.id = buildBranchId(root.rank,"");
		root.id = buildBranchId(root.rank,this.parentId);
		root.parentId = this.parentId;
		root.tree = this.tree;
//		System.out.println("IupacBranch.getRootFromBranch() : " + root_seq);
		
		return root;
	}
	
	protected ArrayList<IupacBranch> getBranches()
	{		
		ArrayList<IupacBranch> branches = new ArrayList<IupacBranch>();
		//sequence without the root
		String branches_seq = this.sequence.substring(0,this.sequence.lastIndexOf(Constants.closingSquareBracket)+1);
		
//		System.out.println("IupacBranch.getBranches() seq : " + branches_seq);
//		System.out.println("IupacBranch.getBranches() length : " + branches_seq.length());
		
		int posIndex=branches_seq.length()-1; //begin with the last element of the string	
		int seqBeginIndex=posIndex; //start at the end
		int branchBracketNumber=0; 
		
		while(branches_seq.length()!=0 && posIndex>=0) //while the whole sequence has not been parsed!
		{
//			System.out.println("IupacBranch.getBranches() posIndex : " + posIndex);
//			System.out.println("IupacBranch.getBranches() branches_seq.charAt(posIndex) : " + branches_seq.charAt(posIndex));
//			System.out.println("IupacBranch.getBranches() seqBeginIndex : "+seqBeginIndex);
			
			countSquareBrackets(branches_seq.charAt(posIndex));// count in counters opening or closing brackets	
//			System.out.println("IupacBranch.getBranches() branchBracketNumber : "+ branchBracketNumber);
			
			String seq="";
			//System.out.println("IupacBranch.getBranches() seq(b) : "+ seq);	
			
			isBranchButNotLast(branches_seq, seqBeginIndex, posIndex);
//			System.out.println("IupacBranch.getBranches() branches_seq : "+ branches_seq);
			
			isLastBranch(branches_seq, seqBeginIndex, posIndex);
			
			if(isLastBranch(branches_seq, seqBeginIndex, posIndex)) //last branch
			{
				seq=branches_seq;
//				System.out.println("IupacBranch.getBranches() seq (last): "+ seq);
				
				IupacBranch	branch = new IupacBranch(seq);
				branch.parentId = this.id;
				branch.level = this.level+1;
				
				branch.rank =branchBracketNumber;
//				branch.id = buildBranchId(branch.level, branch.rank);
				branch.id = buildBranchId(branch.rank,this.id);
				branch.tree = this.tree;
				branch.toString();				
				branches.add(branch);
				
				seqBeginIndex=posIndex-1;
				branchBracketNumber++;
			}
			else if(isBranchButNotLast(branches_seq, seqBeginIndex, posIndex)) //branch but not last
			{
				seq=branches_seq.substring(posIndex);
//				System.out.println("IupacBranch.getBranches() seq (NOT last) : "+ seq);
				branches_seq= branches_seq.substring(0, posIndex);
//				System.out.println("IupacBranch.getBranches() branches_seq (NOT last) : "+ branches_seq);
			
				IupacBranch	branch = new IupacBranch(TreeTools.removeBrackets(seq));
				branch.parentId = this.id;
				branch.level = this.level+1;
				branch.rank =branchBracketNumber;
				branch.id = buildBranchId(branch.rank, this.id);
				branch.tree = this.tree;
				branch.toString();				
				branches.add(branch);
					
				seqBeginIndex=posIndex-1;
				branchBracketNumber++;
			}
//			else
//			{
//				/*do nothing*/
//				System.out.println("IupacBranch.getBranches() ??!!! ");
//			}
			
			posIndex--;
		}
			//scan the sequence backward
			
		return branches;		
	}	
	
	
	protected void setResidues() throws Exception
	{
		residues.clear();
//		IupacResidue residue = null;
		//ArrayList<IupacResidue> residues = new ArrayList<IupacResidue>();
		// split in residues with link to next abstractResidue!!!
		
		int posIndex=this.sequence.length()-1; //begin with the last element of the string	
		int seqBeginIndex=posIndex; //start at the end
		int branchResidueNumber=0;

		String multitudeRange = "";
		
		/*scan the sequence for parenthesis*/
		while(posIndex>=0)
		{
			countParenthesis(this.sequence.charAt(posIndex));//count in counters opening or closing brackets	
			String seq="";
			
			/*Condition for any residue except last one on the left WITH repeats*/
			if(openingParenthesisCount == closingParenthesisCount && this.sequence.charAt(posIndex) == Constants.closingCurlyBracket)
			{
				
				int closingCurlybracketPosition=posIndex;
				int openingCurlybracketPosition=getRepeatStartIndex(this.sequence,closingCurlybracketPosition);
				multitudeRange = TreeTools.getMultitude(this.sequence, closingCurlybracketPosition);
				int[] multitude= TreeTools.getMultitudeMinMax(multitudeRange);
				System.out.println("IupacBranch.setResidues() multitude : "+ multitudeRange);
				
				/*addToResidues current residue (from the root, the last before ) without '}multitude'*/				
				branchResidueNumber = addToResidues(this.sequence, posIndex+multitudeRange.length()+1, seqBeginIndex+1, branchResidueNumber);
				
				
				
				/*create virtual residue Rep and add repeat sequence and multitude, then add to residues and increment branchResidueNumber*/
				String repSeq = TreeTools.removeBrackets(sequence.substring(openingCurlybracketPosition,closingCurlybracketPosition+1));
//				System.out.println("IupacBranch.setResidues() repeat seq : " + repSeq);
				
				/*create the repeat tree and add it to the residue*/
				IupacRepeatTree repeatTree = new IupacRepeatTree(repSeq,multitude[0],multitude[1]);//Integer.parseInt(multitudeRange),Integer.parseInt(multitudeRange));
//				System.err.println("IupacBranch.setResidues() repeat tree: "+ repeatTree.getSequence());
				
				//FIXME
				TreeTools.getTopTreeRepeat(this.getTree()).addToRepeats(repeatTree);
				//this.getTopTree().addToRepeats(repeatTree);
				//repeatTree.getTopTree(repeatTree).addToRepeats(repeatTree);
				
				branchResidueNumber = addToResidues(this.sequence,openingCurlybracketPosition+1, closingCurlybracketPosition,branchResidueNumber,repeatTree);				
				
				/*move to residue after the repeat*/
				try
				{
				posIndex = openingCurlybracketPosition-1;
				countParenthesis(this.sequence.charAt(posIndex));
//				System.out.println("IupacBranch.setResidues() current char : " + this.sequence.charAt(posIndex));
				seqBeginIndex=posIndex;
				}
				catch(Exception ex)
				{
					System.err.println("No residue after the repeat");
				}
			}
			
			
			/*Condition for any residue except last one on the left with NO repeats*/
			if(openingParenthesisCount+1 == closingParenthesisCount && this.sequence.charAt(posIndex) == Constants.closingParenthesis)// && openingParenthesisCount!=0)
			{
//				seq=this.sequence.substring(posIndex+1,seqBeginIndex+1);
//				System.out.println("IupacBranch.addToResidues() : "+ (posIndex+1) + " : " + (seqBeginIndex+1) + " / " + seq );
				branchResidueNumber = addToResidues(this.sequence,posIndex+1,seqBeginIndex+1, branchResidueNumber);
//				branchResidueNumber = addToResidues(seq, branchResidueNumber);
				seqBeginIndex=posIndex;
			}
			/*last residue on the left of the linear sequence*/
			if(posIndex==0)
			{
//				seq=this.sequence.substring(posIndex,seqBeginIndex+1);
//				System.out.println("IupacBranch.addToResidues() : "+ posIndex + " : " + (seqBeginIndex+1) + " / " + seq );
				branchResidueNumber = addToResidues(this.sequence,posIndex,seqBeginIndex+1, branchResidueNumber);
//				branchResidueNumber = addToResidues(seq, branchResidueNumber);
			}
			
			posIndex--;
		}
	}
	
	public int getRepeatStartIndex(String sequence, int pos)
	{		
		countCurlyBrackets(this.sequence.charAt(pos));
		while(pos>=0 && openingCurlyBracketCount != closingCurlyBracketCount)
		{
			pos--;
			countCurlyBrackets(this.sequence.charAt(pos));
//			System.err.println("IupacBranch.getRepeatStartIndex() loop opening/closing curlyBracketCount: " +openingCurlyBracketCount+"/"+closingCurlyBracketCount);
//			System.err.println("IupacBranch.getRepeatStartIndex() loop : "+ this.sequence.charAt(pos) + " " + pos);
		}
//		System.err.println("IupacBranch.getRepeatStartIndex() : "+ this.sequence.charAt(pos) + " " + pos);
		return pos;
	}
	
	public int addToResidues(String sequence,int start, int end, int residueNumber, IupacRepeatTree repeat) throws Exception
	{
		try
		{
			IupacResidue r = new IupacResidue(this);
			repeat.setResidue(r);
			System.err.println("repeat.setResidue(r); " + r);
			System.err.println("repeat.setResidue(r) branch; " + r.getBranch());
			System.err.println("repeat.setResidue(r) tree; " + r.getBranch().getTree());
			String seq="Rep"+ Constants.openingParenthesis + r.buildLinkSequence(repeat.getSequence()) + Constants.closingParenthesis;
			//System.out.println("IupacBranch.addToResidues() Repeat : "+seq + "/"+ sequence+" "+ start+" "+ end);
			
			if(seq.length() != 0)
			{
				System.out.println("IupacBranch.addToResidues() : "+ residueNumber + " / " + seq + " isRepeat: "+ (repeat!=null) );
				IupacResidue residue = TreeTools.removeAglyconRoot(new IupacResidue(seq, residueNumber, this, repeat));
//				residue.setRepeat(new IupacRepeatTree(repeatSequences));
				
//				System.out.println("IupacBranch.addToResidues()2 : "+ residueNumber + " / " + seq + " isRepeat: "+ isRepeat);
				if(residue!=null)
				{	
					this.residues.add(residue);
					residueNumber++;
				}	
			}
		}
		catch(Exception ex)
		{
//			System.err.println("IupacBranch.addToResidues() : " + ex.toString());
//			ex.printStackTrace();
			throw ex;
		}
		return residueNumber;
	}
	
	public int addToResidues(String sequence,int start, int end, int residueNumber) throws Exception
	{
		try
		{
			
			String seq=sequence.substring(start,end);
//			System.err.println("IupacBranch.addToResidues() : "+seq + "/"+ sequence+" "+ start+" "+ end);
			
			if(seq.length() != 0)
			{
//				System.out.println("IupacBranch.addToResidues() : "+ residueNumber + " / " + seq );
				IupacResidue residue = TreeTools.removeAglyconRoot(new IupacResidue(seq, residueNumber, this));
//				residue.setRepeat(new IupacRepeatTree(repeatSequences));
				
//				System.out.println("IupacBranch.addToResidues()2 : "+ residueNumber + " / " + seq + " isRepeat: "+ isRepeat);
				if(residue!=null)
				{
					this.residues.add(residue);
					residueNumber++;
				}	
			}
		}
		catch(Exception ex)
		{
//			System.err.println("IupacBranch.addToResidues() : " + ex.toString());
			throw ex;
//			ex.printStackTrace();
		}
		return residueNumber;
	}
	
	
	public IupacResidue getResidue(int residueIdx)
	{
		return this.residues.get(residueIdx);
	}
	
	
	
	protected String buildBranchId(Integer rank, String parentId)
	{	
		String id="";
		
		id= parentId + rank.toString(); //String.valueOf(rank);
//		System.out.println("IupacBranch.buildBranchId(rank "+ rank + ", parentId "+ parentId+") : "+ id);
		return id;
	}
	
	protected boolean isBranchButNotLast(String seq, int start, int end)
	{
		boolean value=false;
		
		if((seq.charAt(end)==Constants.openingSquareBracket)&&(seq.charAt(start)==Constants.closingSquareBracket)&&isEqualSquareBracketCount())
		{
			value=true;
//			System.out.println("IupacBranch.isBranchButNotLast() value : " + value + " : " + seq.substring(end)+ " : " +end +","+seq.charAt(end) + " : " +start+","+seq.charAt(start) );
		}
		return value;
	}
	
	protected boolean isLastBranch(String seq, int start, int end)
	{
		boolean value=false;
		
		if((seq.charAt(end)!=Constants.openingSquareBracket)&&(seq.charAt(start)==')')&&(start!=end)&&isEqualSquareBracketCount())
		{
			value=true;
//			System.out.println("IupacBranch.isLastBranch() value : " + value + " : " + seq.substring(end,start)+ " : " +end +","+seq.charAt(end) + " : " +start+","+seq.charAt(start) );
		}		
		return value;
	}
	
	protected boolean isBranch(String seq, int start, int end)
	{
		boolean value=false;
		
		if(isLastBranch(seq, start, end)||isBranchButNotLast(seq, start, end))
		{
			value=true;
		}		
		return value;
	}
	
	protected boolean isEqualSquareBracketCount()
	{
		boolean value=false;
		
		if(openingSquareBracketCount==closingSquareBracketCount)
		{
			value=true;
//			System.out.println("IupacBranch.isEqualSquareBracketCount() value : "+value);
		}		
		return value;
	}
	
	protected boolean isEqualCurlyBracketCount()
	{
		boolean value=false;
		
		if(openingCurlyBracketCount==closingCurlyBracketCount)
		{
			value=true;
//			System.out.println("IupacBranch.isEqualCurlyBracketCount() value : "+value);
		}		
		return value;
	}
	
	protected void countSquareBrackets(char c)
	{
		if(c == Constants.openingSquareBracket)
		{
			openingSquareBracketCount++;
//			System.out.println("IupacBranch.countBrackets() openingSquareBracket/closingSquareBracket : " + openingSquareBracketCount+"/"+closingSquareBracketCount);
		}
		
		if(c==Constants.closingSquareBracket)
		{
			closingSquareBracketCount++;
//			System.out.println("IupacBranch.countBrackets() openingSquareBracket/closingSquareBracket : " + openingSquareBracketCount+"/"+closingSquareBracketCount);
		}
		else
		{
			//System.out.println("IupacBranch.countBrackets() : not a bracket!! " + c);
		}
//		System.out.println("IupacBranch.countBrackets() openingSquareBracket/closingSquareBracket : " + openingSquareBracketCount+"/"+closingSquareBracketCount);
	}
	
	protected void countCurlyBrackets(char c)
	{
		if(c == Constants.openingCurlyBracket)
		{
			openingCurlyBracketCount++;
//			System.out.println("IupacBranch.countBrackets() openingSquareBracket/closingSquareBracket : " + openingSquareBracketCount+"/"+closingSquareBracketCount);
		}
		
		if(c==Constants.closingCurlyBracket)
		{
			closingCurlyBracketCount++;
//			System.out.println("IupacBranch.countBrackets() openingSquareBracket/closingSquareBracket : " + openingSquareBracketCount+"/"+closingSquareBracketCount);
		}
		else
		{
			//System.out.println("IupacBranch.countBrackets() : not a bracket!! " + c);
		}
//		System.out.println("IupacBranch.countCurlyBrackets() openingCurlyBracket/closingCurlyBracket : " + openingCurlyBracketCount+"/"+closingCurlyBracketCount);
	}
	
	protected void countParenthesis(char c)
	{
		if(c == Constants.openingParenthesis)
		{
			openingParenthesisCount++;
		}
		
		if(c==Constants.closingParenthesis)
		{
			closingParenthesisCount++;
		}
		else
		{
			//System.out.println("IupacBranch.countBrackets() : not a bracket!! " + c);
		}
//		System.out.println("IupacBranch.countParenthesis() openingParenthesis/closingParenthesis : " + openingParenthesisCount+"/"+closingParenthesisCount);
	}

	public int hasComposedResidue()
	{
		int result = 0;
		for(int i=0;i<residues.size();i++)
		{
			if(residues.get(i).isComposedResidue())
			{	
				result++;
			}
		}
		return result;	
	}
	
	
//	public ArrayList<CTBranch> expand(ArrayList<IupacBranch> branchesToExpand)//int parentLevel, int parentsChildrenMaxRank)
//	{
//		//ArrayList<IupacBranch> branchesExpanded = new ArrayList<IupacBranch>();
//		ArrayList<CTBranch> branchesExpanded = new ArrayList<CTBranch>();
//		
//		System.out.println("IupacBranch expand " + this.id + " isExpanded() : " + isExpanded());
//		if(!isExpanded())
//		{
//			ctBranches.addAll(splitCT());
//			//branchesExpanded.addAll(splitCT());
//		}
//		else
//		{			
//			if(TreeTools.hasChildrenBranches(this, branchesToExpand))
//			{
//				ArrayList<IupacBranch> children = TreeTools.getChildrenBranches(this, branchesToExpand);
//				System.out.println("IupacBranch expand children  : " + TreeTools.getChildrenBranches(this, branchesToExpand));
//				for(int j =0; j<children.size();j++)
//				{
//					System.out.println("IupacBranch expand child  : " + children.get(j));
//					branchesExpanded.addAll(children.get(j).expand(branchesToExpand));
//				}
//			}	
//		}
//		
//		return branchesExpanded;
//	}

//	public ArrayList<CTBranch> splitCT()//int branchLevel, int branchRank)
//	{
//		//FIXME
//		System.out.println("IupacBranch splitCT()");
//		ArrayList<CTBranch> branchesExpanded = new ArrayList<CTBranch>();
//		CTBranch main = new CTBranch();
//		int mainLevel=0;
//		int mainRank=0;
//		
//		if(level==0 && rank==0)
//		{
//			mainLevel=level;
//			mainRank=rank;
//			
//			main.setLevel(level);
//			main.setRank(rank);
//			main.setId("0"); //buildBranchId(main.getRank(),"");
//			System.out.println("IupacBranch splitCT() root : " + main + " " + main.id);
//		}
//		else
//		{
//			
//			//FIXME
//			mainLevel=0;
//			mainRank=0;
//			main.setId(main.buildBranchId(mainRank, ctId));
////			mainLevel=?;
////			mainRank=?;
////			main.buildBranchId()
//			//////////////////////////////////////////
//			//////////////////////////////////////////
//			//////////////////////////////////////////
//			//////////////////////////////////////////
//			//////////////////////////////////////////
//			
////			int lev = TreeTools.get
////			main.setLevel(level);
////			int ran = TreeTools.getP
//		}
//		
//		branchesExpanded.add(main);
//		
//		for(int i=0;i<residues.size();i++)
//		{
//			IupacResidue residue = residues.get(i);
//			if(!residue.isComposedResidue())
//			{	
//				System.out.println("IupacBranch splitCT() residue : " + residue.toString() + " isComposedResidue() false : "+ residue.isComposedResidue());
//				main.residues.add(residue);
//				residue.buildResidueId();
//				residue.getAbstractResidue().toString();
//			}
//			else
//			{
//				System.out.println("IupacBranch splitCT() residue : " + residue.toString() + " isComposedResidue() true : "+ residue.isComposedResidue());				
//				IupacResidue monosacRes = new IupacResidue(main);
//				monosacRes.buildResidueId();
//				System.out.println("IupacBranch splitCT() splitRes : "+monosacRes + " " +monosacRes.getBranch()); 
//				System.out.println("IupacBranch splitCT() splitRes ID : "+monosacRes.getId() + " " +monosacRes.getBranch().getId()); 
//				
//				GenericMonosaccharideResidue monosac = ((GenericComposedResidue)residue.getAbstractResidue()).getMonosaccharide();
//				System.out.println("IupacBranch splitCT() monosac residue : " + monosac);
//				monosacRes.setAbstractResidue(monosac);
//				
//				monosac.toString();
//				
//				main.residues.add(monosacRes);
//				System.out.println("IupacBranch splitCT() new residue : " + monosacRes);
//								
//				
//				ArrayList<GenericSubstituentResidue> subs = ((GenericComposedResidue)residue.getAbstractResidue()).getSubstituents();
//				System.out.println("IupacBranch splitCT() subs residues : " + subs + " ("+ subs.size()+")");
//				for(int j=0; j<subs.size(); j++)
//				{
//					CTBranch b = new CTBranch();
//					b.setLevel(mainLevel+1);
//					b.setRank(mainRank+j);
//					b.setParentId(main.id);
//					b.setId(b.buildBranchId(b.rank, main.id));
//					b.toString();
//					IupacResidue r = new IupacResidue(b);
//					b.residues.add(r);
//					r.setRank(0);
//					
//					r.setId(r.buildResidueId());
//					r.setAbstractResidue(subs.get(j));
//					
//					subs.get(j).toString();
//					
//					branchesExpanded.add(b);
//					System.out.println("IupacBranch splitCT() subs index+1 : "+(j+1)+" ID : " +monosacRes.getId() + " branchId : " +monosacRes.getBranch().getId()); 
//					
//				}
//				
//
//			}
//		}
//		this.isExpanded = true;
//		
//		return branchesExpanded;	
//	}
	
	@Override
	public String toString() {
//		System.out.println("IupacBranch.toString() : " + super.toString());
//		System.out.println("	ID : " + this.id );
//		System.out.println("	Sequence : " + this.sequence );
//		System.out.println("	Parent : " + this.parentId );
//		System.out.println("	Level : " + this.level );
//		System.out.println("	Rank : " + this.rank );
//		System.out.println("	IupacLength : " + this.iupacLength );
//		System.out.println("	CtLength : " + this.ctLength );
//		System.out.println("	Tree : " + this.tree );
		
		return super.toString();
	}

	
	
//	public void insertNewResidue(int position, IupacResidue res)
//	{	
//		ArrayList<IupacResidue> residues = getResiduesList();
//		residues.add(position, res);
//		System.out.println("IupacBranch insertNewResidue : " + res.toString() + " on position " + position);
//	}
	
//	public void shiftResidues(int position)
//	{
//		System.out.println("IupacBranch shiftResidues from position : " + position);
//		ArrayList<IupacResidue> residues= this.residues;
//		for(int i=position;i<residues.size();i++)
//		{
//		residues.get(i).setRank(rank+1);
//		residues.get(i).buildResidueId();
//		System.err.println("IupacBranch shiftResidues abstractResidue : " + residues.get(i)
//							+ "/ equence : " + residues.get(i).getSequence()
//							+ "/ rank : " + residues.get(i).getRank()
//							+ "/ id : " + residues.get(i).getId()
//							);
//		
//		}
//		
//		//loop on rank increment+buildId
//	}
	
	
}
